import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;

import javax.swing.*;

public class GridPanel extends JPanel implements MouseMotionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Arrow currentArrow;
	private Grid grid;
	private boolean hasOneStart = false,hasOneFinish = false;

	public enum ActionType{
		NONE,
		DRAW_ACTIVITY,
		DRAW_DECISION,
		DRAW_ARROW,
		DRAW_START_NODE,
		DRAW_FINISH_NODE
	}
	
	ActionType action;
	
	public GridPanel() {
		super();
		currentArrow=null;
		grid=new Grid(15,this);
		action=ActionType.NONE;
		setBackground(Color.WHITE);
		setLayout(null);
		setOpaque(false);
		addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent event){
				mouseClickedEvent(event);
			}
		});
		addMouseMotionListener(this);
	}

	public void setAction(ActionType action){
		this.action=action;
	}
	
	public ActionType getAction(){
		return action;
	}
	
	public void paintComponent(Graphics g) {
		grid.drawGrid(g);

	}

	public void mouseClickedEvent(MouseEvent event){
		Element element=null;
		
		if (action==ActionType.DRAW_ACTIVITY) {

			element = new Activity("Work", grid.round(event.getX()), grid.round(event.getY()),this);
		}
		
		if (action==ActionType.DRAW_DECISION) {
			element = new Decision( grid.round(event.getX()), grid.round(event.getY()),this);
		}
		
		if ((action==ActionType.DRAW_START_NODE)&&(!hasOneStart)) {
			element = new StartNode( grid.round(event.getX()), grid.round(event.getY()),this);
			hasOneStart = true;
		}
		
		if ((action==ActionType.DRAW_FINISH_NODE)&&(!hasOneFinish)) {
			element = new FinishNode( grid.round(event.getX()), grid.round(event.getY()),this);
			hasOneFinish = true;
		}
		
		if(element!=null){
			element.addMouseMotionListener(new MouseMotionListener() {
				
				@Override
				public void mouseMoved(MouseEvent e) {
					// TODO Auto-generated method stub
					elementMouseMoved(e);
					
				}
				
				@Override
				public void mouseDragged(MouseEvent e) {
					// TODO Auto-generated method stub
					
				}
			});
			add(element);
			element.repaint();
		}
		
		if (action==ActionType.DRAW_ARROW&&drawingArrow()){
			if(event.getButton()==MouseEvent.BUTTON1)
				currentArrow.addVertex();
			else
				if(event.getButton()==MouseEvent.BUTTON3)
					currentArrow.deleteVertex();
		}
	}
	
	public void setGridStep(int step){
		grid.setStep(step);
	}
	
	public int round(int x){
		return grid.round(x);
	}
	
	public Point round(Point p){
		return grid.round(p);
	}
	
	public void elementSelected(Element el){
		if(drawingArrow()){
			currentArrow.finish(el);
			currentArrow=null;
		}
		else{
			currentArrow=new Arrow(el,this);
		}
	}
	
	public void mouseUnderElement(Element el){
		if(drawingArrow()){
			currentArrow.moveEndPoint(new Point(el.getCenterX(),el.getCenterY()));
		}
	}
	
	public void cancelArrow(){
		currentArrow=null;	
	}
	
	private void drawArrow(Element el1,Element el2){
		//new Arrow(el1, el2, this);
	}
	
	public boolean drawingArrow(){
		return currentArrow!=null;
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		if(drawingArrow()){
			currentArrow.moveEndPoint(e.getPoint());
			currentArrow.removeEndElement();
		}		
	}
	
	public void elementMouseMoved(MouseEvent e){
		if(drawingArrow())
			currentArrow.finish((Element)e.getSource());
	}
}
